﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.ServiceModel.Configuration;
using System.Text;
using System.Windows.Forms;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Service.Contact.Message;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.Service.Contact.Message.Item;
using VNet.VisiSuite.Service.Contact.Message.Security;
using VNet.VisiSuite.Service.Proxy;
using VNet.VisiSuite.VisiBoard.BusinessLogic;
using VNet.VisiSuite.VisiBoard.Common.Helpers;

namespace VNet.VisiSuite.VisiBoard.Providers
{
    public class SyncProvider
    {

        public class SyncProviderData
        {
            public int CellId { get; set; }
            public string Password { get; set; }
            public string InstallKey { get; set; }
            public string ServiceUrl { get; set; }
            public List<TableDataChangeItem> TablesChanges { get; set; }
        }

        public static void VerifyCellAndGetServerData(object sender, DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            e.Result = null;

            if (worker != null && worker.CancellationPending == false)
            {
                var data = (SyncProviderData)e.Argument;
                if (!string.IsNullOrEmpty(data.ServiceUrl) && !MappingClientEndpointAddress(data.ServiceUrl))
                {
                    e.Result = new ConfigureResponse { Success = false, Error = new ServiceError { Description = ErrorMessages.ServiceUrlInvalid } };
                }
                else
                {
                    using (var client = new VNetVisiSuiteContractClient())
                    {
                        var request = new ConfigureRequest
                        {
                            CellId = data.CellId,
                            Password = data.Password,
                            InstallKey = data.InstallKey,
                            TableChanges = data.TablesChanges
                        };
                        e.Result = client.VerifyCellAndGetServerData(request);
                    }
                }
            }
        }

        public static void SyncDataFromServerToClient(object sender, DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            e.Result = null;

            if (worker != null && worker.CancellationPending == false)
            {
                using (var client = new VNetVisiSuiteContractClient())
                {
                    var request = new ConfigureRequest
                    {
                        CellId = NavigationManager.CurrentCell.CellId,
                        Password = NavigationManager.CurrentCell.Password,
                        TableChanges = e.Argument as List<TableDataChangeItem>
                    };
                    var response = client.SyncDataFromServerToClient(request);
                    if (response.Success)
                    {
                        var local = new LocalUtil();
                        e.Result = local.SyncDataFromServerToClient(response);
                    }
                    else
                    {
                        e.Result = response;
                    }
                }
            }
        }

        public static void SyncDataFromClientToServer1(object sender, DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            e.Result = null;
            if (worker != null && worker.CancellationPending == false)
            {
                var data = e.Argument as LocalData;
                if (data == null)
                {
                    var pre_sync_response = ClientSyncUtil.PreSyncFromClientToServer();
                    if (pre_sync_response.Success)
                        data = pre_sync_response.Data;
                }
                using (var client = new VNetVisiSuiteContractClient())
                {
                    var request = new SyncDataFromClientRequest
                    {
                        CellId = NavigationManager.CurrentCell.CellId,
                        Password = NavigationManager.CurrentCell.Password,
                        LocalData = data,
                    };
                    e.Result = client.SyncDataFromClientToServer(request);
                }
            }
        }

        public static void SyncDataFromClientToServer(object sender, DoWorkEventArgs e)
        {
            var worker = sender as BackgroundWorker;
            var result = new ServiceBaseResponse();
            result.Success = false;

            if (worker != null && worker.CancellationPending == false)
            {

                var pre_sync_response = ClientSyncUtil.PreSyncFromClientToServer();

                if (pre_sync_response.Success == false)
                {
                    result = pre_sync_response;
                }
                else
                {
                    SyncDataFromClientResponse sync_response = null;
                    using (var client = new VNetVisiSuiteContractClient())
                    {
                        var request = new SyncDataFromClientRequest
                        {
                            CellId = NavigationManager.CurrentCell.CellId,
                            Password = NavigationManager.CurrentCell.Password,
                            LocalData = pre_sync_response.Data,
                        };
                        sync_response = client.SyncDataFromClientToServer(request);
                    }
                    if (sync_response.Success == false)
                    {
                        result = sync_response;
                    }
                    else
                    {
                        result = ClientSyncUtil.PostSyncFromClientToServer(sync_response);
                    }

                }
 

            }
            e.Result = result;
        }

        private static bool MappingClientEndpointAddress(string url)
        {
            try
            {
                string httpStr = "http://";
                int index = url.IndexOf(httpStr);
                url = (index < 0) ? url : url.Remove(index, httpStr.Length);

                if (url[url.Length - 1] == '/')
                    url = url.Remove(url.Length - 1);

                // Get the application configuration file.
                var config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

                var endpoints = ((ClientSection)config.SectionGroups["system.serviceModel"].Sections["client"]).Endpoints;
                foreach (ChannelEndpointElement endpoint in endpoints)
                {
                    var uri = string.Format(@"{0}{1}/{2}", httpStr, url, endpoint.Address.AbsolutePath.Contains("VNetVisiSuiteService.svc/VNetVisiSuiteService") ? "VNetVisiSuiteService.svc/VNetVisiSuiteService" : "VNetVisiSuiteSecurityService.svc/VNetVisiSuiteSecurityService");
                    endpoint.Address = new Uri(uri);
                }
                // Save the configuration file.
                config.Save(ConfigurationSaveMode.Modified);

                ConfigurationManager.RefreshSection("system.serviceModel/client");

                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
